/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.dusin.teachassist.servlet.util;

import com.google.gson.Gson;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;

import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebInitParam;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.dusin.teachassistdbservice.serviceimpl.GeneralService;
//import org.imgscalr.Scalr;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 *
 * @author dusin
 */
@WebServlet(name = "UploadExcelFile",
        urlPatterns = {"/util/UploadExcelFile"},
        initParams = {
            @WebInitParam(name = "upload_path", value = "e:/ta")
        }
)
public class UploadExcelFile extends HttpServlet {

    private File fileUploadPath;
    private GeneralService instance;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config); //To change body of generated methods, choose Tools | Templates.
        fileUploadPath = new File(config.getInitParameter("upload_path"));
    }

    /**
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code>
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if (!ServletFileUpload.isMultipartContent(request)) {
            throw new IllegalArgumentException("Request is not multipart, please 'multipart/form-data' enctype for your form.");
        }

        ServletContext servletConfig = this.getServletContext();
        String dataDirectoryStr = servletConfig.getInitParameter("DataDirectory");
        if(dataDirectoryStr==null){
            dataDirectoryStr= "e:/ta";
        }
        ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
        instance = (GeneralService) context.getBean("generalService");
        // Create a factory for disk-based file items
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // Configure a repository (to ensure a secure temp location is used)
            ServletContext servletContext = this.getServletConfig().getServletContext();
            File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
            //System.out.println("repository:" + repository.getAbsolutePath());
            factory.setRepository(repository);
        ServletFileUpload uploadHandler = new ServletFileUpload(factory);
        uploadHandler.setHeaderEncoding("utf-8");  //可以解决中文文件名乱码问题
        response.setContentType("application/json");  //这句放在PrintWriter之前，解决乱码问题
        response.setCharacterEncoding("utf-8");
        //response.setContentType("application/json;charset=UTF-8");  解决中文乱码
        PrintWriter writer = response.getWriter();        
        
        //JSONArray json = new JSONArray();     //响应数据为数组，为后面一次上传多个文件做准备
        Gson gson = new Gson();
        Map<String,Object> resultMap = new HashMap<>();
        try {
            FileItemIterator iter = uploadHandler.getItemIterator(request);
            while (iter.hasNext()) {
                FileItemStream item = iter.next();
                if (!item.isFormField()) {
                    //File file = new File(fileUploadPath, item.getName());
                    //item.write(file);                    
                    String name = item.getFieldName();
                    InputStream stream = item.openStream();
                    Map<String, Object> result = instance.createFromRoster(stream);
                    String teacherNo=null;
                    if(result.get("teacher")!=null){
                        teacherNo = ((String)result.get("teacher")).split("[|]")[1];  //取出教师工号
                        //创建存放该教师文件的目录
                        Path dataPath = Paths.get(dataDirectoryStr+"/"+teacherNo+"/");
                        if(Files.notExists(dataPath)){
                            Files.createDirectories(dataPath);
                        }
                    }
                    String semester= null;
                    String courseName = null; //课程名称
                    String classInfo = (String)result.get("class");
                    if(classInfo!=null){
                        semester = classInfo.split("[|]")[2];  //取出学期
                        Path dataPath = Paths.get(dataDirectoryStr+"/"+teacherNo+"/"+semester+"/");
                        if(Files.notExists(dataPath)){
                            Files.createDirectories(dataPath);
                        }
                        courseName = ((String)result.get("class")).split("[|]")[1];  //取出课程名称
                        dataPath = Paths.get(dataDirectoryStr+"/"+teacherNo+"/"+semester+"/"+courseName+"/"+"实验/");
                        if(Files.notExists(dataPath)){
                            Files.createDirectories(dataPath);
                        }
                        dataPath = Paths.get(dataDirectoryStr+"/"+teacherNo+"/"+semester+"/"+courseName+"/"+"作业/");
                        if(Files.notExists(dataPath)){
                            Files.createDirectories(dataPath);
                        }
                    }
                    
                    
                    resultMap.put("name", item.getName());
                    resultMap.put("status", true);
                    resultMap.put("result", result);
                    resultMap.put("msg", "上传成功");
                    
                }
            }
        } catch (Throwable t) {            
            resultMap.put("status", false);
            resultMap.put("msg",t.getMessage());           
            t.printStackTrace();
        } finally {
            writer.write(gson.toJson(resultMap));
            writer.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if (request.getParameter("getfile") != null
                && !request.getParameter("getfile").isEmpty()) {
            File file = new File(fileUploadPath,
                    request.getParameter("getfile"));
            if (file.exists()) {
                int bytes = 0;
                ServletOutputStream op = response.getOutputStream();

                response.setContentType(getMimeType(file));
                response.setContentLength((int) file.length());
                response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");

                byte[] bbuf = new byte[1024];
                DataInputStream in = new DataInputStream(new FileInputStream(file));

                while ((in != null) && ((bytes = in.read(bbuf)) != -1)) {
                    op.write(bbuf, 0, bytes);
                }

                in.close();
                op.flush();
                op.close();
            }
        } else if (request.getParameter("delfile") != null && !request.getParameter("delfile").isEmpty()) {
            File file = new File(fileUploadPath, request.getParameter("delfile"));
            if (file.exists()) {
                file.delete(); // TODO:check and report success
            }
        } else if (request.getParameter("getthumb") != null && !request.getParameter("getthumb").isEmpty()) {
            File file = new File(fileUploadPath, request.getParameter("getthumb"));
            if (file.exists()) {
                String mimetype = getMimeType(file);
                if (mimetype.endsWith("png") || mimetype.endsWith("jpeg") || mimetype.endsWith("gif")) {
                    BufferedImage im = ImageIO.read(file);
                    if (im != null) {
                        //BufferedImage thumb = Scalr.resize(im, 75); 
                        BufferedImage thumb = im;
                        ByteArrayOutputStream os = new ByteArrayOutputStream();
                        if (mimetype.endsWith("png")) {
                            ImageIO.write(thumb, "PNG", os);
                            response.setContentType("image/png");
                        } else if (mimetype.endsWith("jpeg")) {
                            ImageIO.write(thumb, "jpg", os);
                            response.setContentType("image/jpeg");
                        } else {
                            ImageIO.write(thumb, "GIF", os);
                            response.setContentType("image/gif");
                        }
                        ServletOutputStream srvos = response.getOutputStream();
                        response.setContentLength(os.size());
                        response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
                        os.writeTo(srvos);
                        srvos.flush();
                        srvos.close();
                    }
                }
            } // TODO: check and report success
        } else {
            PrintWriter writer = response.getWriter();
            writer.write("call POST with multipart form data");
        }
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    private String getMimeType(File file) {
        String mimetype = "";
        if (file.exists()) {
//            URLConnection uc = new URL("file://" + file.getAbsolutePath()).openConnection();
//            String mimetype = uc.getContentType();
//            MimetypesFIleTypeMap gives PNG as application/octet-stream, but it seems so does URLConnection
//            have to make dirty workaround
            if (getSuffix(file.getName()).equalsIgnoreCase("png")) {
                mimetype = "image/png";
            } else {
                javax.activation.MimetypesFileTypeMap mtMap = new javax.activation.MimetypesFileTypeMap();
                mimetype = mtMap.getContentType(file);
            }
        }
        System.out.println("mimetype: " + mimetype);
        return mimetype;
    }

    private String getSuffix(String filename) {
        String suffix = "";
        int pos = filename.lastIndexOf('.');
        if (pos > 0 && pos < filename.length() - 1) {
            suffix = filename.substring(pos + 1);
        }
        System.out.println("suffix: " + suffix);
        return suffix;
    }
}
